<template>
  <div class="page-table">
    <div class="operation">
      <slot name="header-operation-left"> </slot>
      <t-button v-if="!noAddEdit" @click="emit('addOrEdit')">新增</t-button>
      <slot name="header-operation-right"> </slot>
    </div>
    <t-table
      rowKey="id"
      :data="data"
      :columns="columns"
      :pagination="pagination"
      :loading="systemStore.Loading"
      stripe
      bordered
      :max-height="maxHeight"
      :expandedRowKeys="expandedRowKeys"
      @expand-change="onExpandChange"
      @page-change="onPageChange"
    >
      <template v-for="col in columns" :key="col.title" v-slot:[col.colKey]="{ row }">
        <!-- 渲染自定义插槽 -->
        <template v-if="slots[col.colKey] && col.colKey !== 'operation'">
          <slot :name="col.colKey" v-bind="row"> </slot>
        </template>
        <!-- 默认内容 -->
        <template v-if="!slots[col.colKey] && col.colKey !== 'operation'">
          {{ row[col.colKey] }}
        </template>
        <!-- 操作列 -->
        <template v-if="col.colKey === 'operation'">
          <slot name="operation_left" v-bind="row"> </slot>
          <t-button
            v-if="!noAddEdit"
            variant="text"
            theme="success"
            size="small"
            @click="emit('addOrEdit', row)"
            >编辑</t-button
          >
          <t-popconfirm
            theme="danger"
            content="确定删除吗?"
            :confirm-btn="{
              content: '确定',
              theme: 'danger'
            }"
            :onConfirm="() => deletePage(row.id)"
          >
            <t-button variant="text" theme="danger" size="small">删除</t-button>
          </t-popconfirm>
          <slot name="operation_right" v-bind="row"> </slot>
        </template>
      </template>
      <template #expandedRow="{ row }" v-if="slots.expandedRow">
        <slot name="expandedRow" v-bind="row"></slot>
      </template>
    </t-table>
  </div>
</template>
<script setup lang="ts">
import { computed, ref, useSlots } from 'vue'
import useSystemStore from '@/stores/main/system'
import type { TableProps } from 'tdesign-vue-next'

const props = defineProps<{
  pageName: string
  header: any[]
  searchForm?: any
  noAddEdit?: boolean
  customCol?: (columns: any[]) => any[]
}>()
const slots = useSlots()

const maxHeight = ref(document.body.clientHeight - 260)
window.onresize = () => {
  maxHeight.value = document.body.clientHeight - 260
}

const systemStore = useSystemStore()
const getPageList = (queryInfo: any = {}) => {
  systemStore.getPageListAction(props.pageName, queryInfo)
}

const data = computed(() => {
  // @ts-ignore
  return systemStore[props.pageName]
})
const columns = computed(() => {
  // @ts-ignore
  const header = props.header
  let width = 120
  let btn_num = (slots.operation_left?.().length || 0) + (slots.operation_right?.().length || 0)
  width = width + btn_num * 40
  header.push({ colKey: 'operation', title: '操作', width, align: 'center' })

  return header
})
const pagination = computed(() => {
  // @ts-ignore
  const paginationInfo = systemStore[`${props.pageName}Pagination`]
  return {
    pageSizeOptions: ['10', '30', '50', '100', '500'],
    pageSize: paginationInfo.per_page,
    total: paginationInfo.total,
    current: paginationInfo.current_page
  }
})
getPageList(props.searchForm)

const onPageChange: TableProps['onPageChange'] = ({ current, pageSize }) => {
  getPageList({ page: current, size: pageSize, ...props?.searchForm })
}

const expandedRowKeys = ref<number[]>([])
const onExpandChange = (keys: number[]) => {
  expandedRowKeys.value = [keys.pop() as number]
}

const emit = defineEmits(['addOrEdit'])

const deletePage = (id: number) => {
  const queryInfo = {
    page: pagination.value.current,
    size: pagination.value.pageSize
  }
  systemStore.deletePageAction(props.pageName, id, queryInfo)
}

defineExpose({
  getPageList,
  pagination
})
</script>

<style scoped lang="less">
.page-table {
  .operation {
    display: flex;
    justify-content: flex-end;
    margin-bottom: 15px;
    button {
      margin-left: 10px;
    }
  }
}
</style>
